﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Collections.ObjectModel;
using JMT.Data;
using System.Windows;
using JMT.Data.Events;

namespace JMT.Controls
{
    public class JMSolutionTree : TreeView, IEventHandler
    {
        Data.JMSolution _solution;
        TreeViewItem tis;

        public JMSolutionTree()
        {
            AllowDrop = true;
        }

        public void Bind(Data.JMSolution solution)
        {
            _solution = solution;

            Items.Clear();

            tis = JTreeNodeFactory.Create(_solution);
            
            //BindDiagrams(tis, solution);
            /*
            solution.DiagramCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(DiagramCollection_CollectionChanged);

            BindPackage(tis, _solution.PackageCollection);
            solution.PackageCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(PackageCollection_CollectionChanged);

            #region interface
            BindInterface(tis, solution.InterfaceCollection);
            solution.InterfaceCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler((sender, e) =>
            {
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    int delta = solution.DiagramCollection.Count + solution.PackageCollection.Count;
                    delta += e.NewStartingIndex;

                    TreeViewItem newTreeNode = CreateInterfaceNode(e.NewItems[0] as JMT.Data.JInterface);
                    tis.Items.Insert(delta, newTreeNode);
                    tis.IsExpanded = true;
                    newTreeNode.IsSelected = true;
                }
            });
            #endregion

            BindClass(tis, solution.ClassCollection);
            solution.ClassCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler((sender, e) =>
            {
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    int delta = solution.DiagramCollection.Count + solution.PackageCollection.Count + solution.InterfaceCollection.Count;
                    delta += e.NewStartingIndex;
                    TreeViewItem newTreeNode = CreateClassNode(e.NewItems[0] as JMT.Data.JClass);
                    tis.Items.Insert(delta, newTreeNode);
                    tis.IsExpanded = true;
                    newTreeNode.IsSelected = true;
                }
            });
            */
            this.Items.Add(tis);
            this.ExpandSubtree(tis);
        }

        private void BindDiagrams(TreeViewItem tidl, IJContainer<JDiagram> jContainer)
        {
            List<JDiagram> diagramList = jContainer.ToList();
            foreach (var jDiagram in diagramList)
            {
                tidl.Items.Add(CreateDiagramNode(jDiagram));
            }
        }

        private TreeViewItem CreateDiagramNode(JMT.Data.JDiagram jDiagram)
        {
            TreeViewItem tic = new JTreeNode(jDiagram);
            return tic;
        }

        protected override void OnMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
        {
            object obj = this.InputHitTest(e.GetPosition(this));
            if (obj is TextBlock)
            {
                TextBlock block = obj as TextBlock;
                if (block.Tag != null && block.Tag is JTreeNode)
                {
                    TreeViewItem selItem = block.Tag as TreeViewItem;
                    selItem.IsSelected = true;
                    if (selItem.DataContext is JMSolution)
                    {
                        ContextMenu menu = ContextMenus.ContextMenuFactory.Get("solutiontreenode");
                        menu.Tag = selItem.DataContext;
                        menu.DataContext = selItem.DataContext;
                        menu.IsOpen = true;
                    }
                    else if (selItem.DataContext is JClass)
                    {
                        ContextMenu menu = ContextMenus.ContextMenuFactory.Get("classtreenode");
                        menu.Tag = selItem.DataContext;
                        menu.DataContext = selItem.DataContext;
                        menu.IsOpen = true;
                    }
                    else if (selItem.DataContext is JPackage)
                    {
                        ContextMenu menu = ContextMenus.ContextMenuFactory.Get("packagetreenode");
                        menu.Tag = selItem.DataContext;
                        menu.DataContext = selItem.DataContext;
                        menu.IsOpen = true;
                    }
                }
            }
            base.OnMouseRightButtonDown(e);
        }

        protected override void OnSelectedItemChanged(System.Windows.RoutedPropertyChangedEventArgs<object> e)
        {
            TreeViewItem selItem = e.NewValue as TreeViewItem;
            if (selItem != null)
            {
                JUI.PropertyPanel.Bind(selItem.Tag);
            }
            base.OnSelectedItemChanged(e);
        }

        protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
        {
            object obj = this.InputHitTest(e.GetPosition(this));
            if (obj is TextBlock)
            {
                TextBlock block = obj as TextBlock;
                if (block.Tag != null && block.Tag is JTreeNode)
                {
                    TreeViewItem selItem = block.Tag as TreeViewItem;
                    selItem.IsSelected = true;
                    if (selItem.DataContext is JDiagram)
                    {
                        JUI.DiagramContainer.Show(_solution, selItem.DataContext as JDiagram);
                    }
                }
            }
            base.OnMouseDoubleClick(e);
        }

        private int GetLastDiagramIndex()
        {
            bool hasItem = false;
            int firstIndex = 0;
            int lastIndex = 0;
            for (int index = 0; index < tis.Items.Count; index++)
            {
                TreeViewItem item = tis.Items[index] as TreeViewItem;
                if (item.Tag is JDiagram)
                {
                    if (!hasItem)
                    {
                        firstIndex = index;
                        lastIndex = firstIndex;
                        hasItem = true;
                    }
                }
                else if (hasItem)
                {
                    lastIndex = index - 1;
                    break;
                }
            }
            return lastIndex;
        }

        private int GetLastPackageIndex()
        {
            int firstIndex = GetLastDiagramIndex() + 1;
            int lastIndex = firstIndex;
            for (int index = firstIndex; index < tis.Items.Count; index++)
            {
                TreeViewItem item = tis.Items[index] as TreeViewItem;
                if (!(item.Tag is JPackage))
                {
                    break;
                }
                else
                {
                    lastIndex = index;
                }
            }
            return lastIndex;
        }

        /// <summary>
        /// 鼠标移动，判断是否可以进行节点拖动操作
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
        {
            if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
            {
                object obj = this.InputHitTest(e.GetPosition(this));
                if (obj is TextBlock)
                {
                    TextBlock block = obj as TextBlock;
                    if (block.Tag != null && block.Tag is JTreeNode)
                    {
                        TreeViewItem selItem = this.SelectedItem as TreeViewItem;
                        if (selItem != null && (selItem.DataContext is JMT.Data.JClass || selItem.DataContext is JMT.Data.JInterface))
                        {
                            DragDropEffects finalDropEffect = DragDrop.DoDragDrop(selItem, selItem.DataContext, DragDropEffects.Copy);
                        }
                    }
                }
            }

            base.OnMouseMove(e);
        }

        public void Handle(EventBase @event)
        {
            //throw new NotImplementedException();
            //JEvent<IJModel> jEvent = @event as JEvent<IJModel>;
            //if (@event is AddModelEvent<JClass>)
            //{
            //    AddModelEvent<JClass> addEvent = @event as AddModelEvent<JClass>;
            //    TreeViewItem parentNode = GetNode(addEvent.JContainer);
            //}
        }
    }
}
